
package com.huaweicloud.saaslanding.install;

import static com.huaweicloud.saaslanding.basic.constant.BizConstant.BUSINESS_PACKAGE;
import static com.huaweicloud.saaslanding.basic.constant.BizConstant.UTIL_PACKAGE;

import com.huaweicloud.saaslanding.basic.constant.UrlConstant;
import com.huaweicloud.saaslanding.basic.exception.BizException;
import com.huaweicloud.saaslanding.install.bootstrap.SetupProcess;
import com.huaweicloud.saaslanding.install.enumeration.SetupEnum;
import com.huaweicloud.saaslanding.install.util.CheckYmlUtil;
import com.huaweicloud.saaslanding.install.util.DomainNameUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;

import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.CompletionException;

/**
 * 功能描述
 *
 * @since 2022-03-17
 */
@SpringBootApplication
@ComponentScan({UTIL_PACKAGE, BUSINESS_PACKAGE})
@Slf4j
public class SaaslandingInstallApplication {
    public static Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8);

    public static void main(String[] args) {
        log.info("-----------配置文件校验中-----------");
        ConfigurableApplicationContext application = SpringApplication.run(SaaslandingInstallApplication.class, args);

        CheckYmlUtil checkYmlUtil = application.getBean(CheckYmlUtil.class);
        try {
            checkYmlUtil.check();
        } catch (Exception e) {
            log.error("配置文件校验未通过，错误信息: {}", e.getMessage());
            exitApplication(application);
            return;
        }

        log.info("-----------配置文件校验完成-----------");

        command(application);
    }

    /**
     * 命令行操作
     *
     * @param application 应用上下文
     */
    public static void command(ConfigurableApplicationContext application) {
        SetupProcess setupProcess = application.getBean(SetupProcess.class);

        String input;
        // 获取输入值
        while (true) {
            // 给出输入指令
            command();
            input = scanner.nextLine();
            if (SetupEnum.isSupportedCommand(input)) {
                SetupEnum setupEnum = SetupEnum.getOrExit(input);
                if (SetupEnum.EXIT.equals(setupEnum)) {
                    break;
                }

                try {
                    setupProcess.execute(setupEnum);
                    if (SetupEnum.INSTALL.equals(setupEnum)) {
                        loginInfo(application);
                        break;
                    }
                } catch (CompletionException e) {
                    log.error("<{}>失败，请根据错误信息检查对应配置，错误信息：", setupEnum.getOperation(), e);
                } catch (BizException e) {
                    log.error("<{}>失败，请检查对应云服务配置是否正确或是否有权限，错误信息：", setupEnum.getOperation(), e);
                } catch (Exception e) {
                    log.error("<{}>失败，错误信息：", setupEnum.getOperation(), e);
                }
            } else {
                log.error("输入错误或为空,请重新输入");
            }
        }

        exitApplication(application);
    }

    /**
     * 对应的输入提示语句
     */
    private static void command() {
        StringBuilder commandStr = new StringBuilder().append("\n-------------------请输入你要执行的操作---------------------")
            .append("\n------初始化操作----------->请输入..0")
            .append("\n------格式化操作----------->请输入..1")
            .append("\n------终止程序------------>请输入..2");
        log.info(commandStr.toString());
    }

    /**
     * 输出登录信息
     *
     * @param application 应用上下文
     */
    private static void loginInfo(ConfigurableApplicationContext application) {
        Environment env = application.getEnvironment();

        boolean isHttps = Boolean.parseBoolean(env.getProperty("saaslanding-install.ssl.enabled"));
        String domainName = DomainNameUtil.getDomainName();
        String uiElbIp = (isHttps ? UrlConstant.HTTPS_PREFIX : UrlConstant.HTTP_PREFIX) + domainName;

        // 给出登录地址和 用户名密码
        StringBuilder outStr = new StringBuilder()
            .append("\n---------------------------------------------------------\n\t部署程序运行完成! 相关信息:\n\t登录地址：\t\t")
            .append(uiElbIp)
            .append("/admin\n\t用户名：\t\t")
            .append(env.getProperty("saaslanding-install.user.userName"))
            .append("\n\t密码：\t\t")
            .append(env.getProperty("saaslanding-install.user.password"))
            .append("\n---------------------------------------------------------");
        log.info(outStr.toString());
    }

    /**
     * 结束
     *
     * @param context 应用上下文
     */
    public static void exitApplication(ConfigurableApplicationContext context) {
        scanner.close();
        log.info("{}......", SetupEnum.EXIT.getOperation());
        int exitCode = SpringApplication.exit(context, () -> 0);
        System.exit(exitCode);
    }
}
